package com.feng.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.feng.chat.common.Common;
import com.feng.chat.dto.KeepAlive;
import com.feng.chat.dto.Result;
import com.feng.chat.entity.TalkRecords;
import com.feng.chat.entity.TalkRecordsVote;
import com.feng.chat.entity.TalkRecordsVoteAnswer;
import com.feng.chat.entity.Users;
import com.feng.chat.mapper.*;
import com.feng.chat.service.ITalkRecordsVoteService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feng.chat.utils.GetUserUtil;
import com.feng.chat.utils.JwtUtil;
import com.feng.chat.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 聊天对话记录（投票消息表） 服务实现类
 * </p>
 *
 * @author dyf
 * @since 2022-05-31
 */
@Service
public class TalkRecordsVoteServiceImpl extends ServiceImpl<TalkRecordsVoteMapper, TalkRecordsVote> implements ITalkRecordsVoteService {
    @Autowired
    private TalkRecordsMapper talkRecordsMapper;

    @Autowired
    private TalkRecordsVoteMapper talkRecordsVoteMapper;

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private GroupMemberMapper groupMemberMapper;

    @Autowired
    private TalkRecordsVoteAnswerMapper talkRecordsVoteAnswerMapper;

    /**
     * 发送投票消息
     *
     * @param uid
     * @param mode
     * @param options
     * @param receiver_id
     * @param title
     * @return
     */
    @Override
    public Result messageVote(Integer uid, Integer mode, List<String> options, Integer receiver_id, String title) {
        TalkRecords talkRecords = new TalkRecords();
        talkRecords.setTalkType(2);
        talkRecords.setMsgType(5);
        talkRecords.setGroupRead(uid.toString());
        talkRecords.setUserId(uid);
        talkRecords.setReceiverId(receiver_id);
        talkRecordsMapper.insert(talkRecords);

        TalkRecordsVote talkRecordsVote = new TalkRecordsVote();
        talkRecordsVote.setRecordId(talkRecords.getId());
        talkRecordsVote.setUserId(talkRecords.getUserId());
        talkRecordsVote.setTitle(title);
        talkRecordsVote.setAnswerMode(mode);
        talkRecordsVote.setAnswerOption(String.join(",", options));
        List<Integer> groupMember = groupMemberMapper.getGroupMember(receiver_id);
        talkRecordsVote.setAnswerNum(groupMember.size());
        talkRecordsVoteMapper.insert(talkRecordsVote);

        KeepAlive keepAlive = new KeepAlive();
        keepAlive.setEvent(Common.EVENT_TALK);


        EventTalkVO eventTalkVO = new EventTalkVO();
        eventTalkVO.setSender_id(talkRecords.getUserId());
        eventTalkVO.setTalk_type(talkRecords.getTalkType());
        eventTalkVO.setReceiver_id(talkRecords.getReceiverId());

        EventTalkDataVO eventTalkDataVO = new EventTalkDataVO();
        eventTalkDataVO.setUser_id(talkRecords.getUserId());
        eventTalkDataVO.setTalk_type(talkRecords.getTalkType());
        eventTalkDataVO.setReceiver_id(talkRecords.getReceiverId());
        eventTalkDataVO.setMsg_type(talkRecords.getMsgType());
        eventTalkDataVO.setIs_revoke(talkRecords.getIsRevoke());
        eventTalkDataVO.setIs_read(talkRecords.getIsRead());
        eventTalkDataVO.setIs_mark(talkRecords.getIsMark());
        eventTalkDataVO.setId(talkRecords.getId());
        eventTalkDataVO.setCreated_at(talkRecords.getUpdatedAt().format(DateTimeFormatter.ofPattern(Common.LOCALDATETIME_FORMATER)));
        Users users = usersMapper.selectById(talkRecords.getUserId());
        eventTalkDataVO.setNickname(users.getNickName());
        eventTalkDataVO.setAvatar(users.getAvatar());

        VoteVO voteVO = new VoteVO();

        DetailVO detailVO = new DetailVO();
        detailVO.setAnswer_mode(talkRecordsVote.getAnswerMode());
        detailVO.setAnswer_num(talkRecordsVote.getAnswerNum());
        detailVO.setAnswered_num(talkRecordsVote.getAnsweredNum());
        detailVO.setId(talkRecordsVote.getId());
        detailVO.setRecord_id(talkRecordsVote.getRecordId());
        detailVO.setStatus(talkRecordsVote.getStatus());
        detailVO.setTitle(talkRecordsVote.getTitle());

        List<AnswerOptionVO> answerOptionVOS = new ArrayList<>();
        String[] answerOptions = talkRecordsVote.getAnswerOption().split(",");
        for (int i = 0; i < answerOptions.length; i++) {
            AnswerOptionVO answerOptionVO = new AnswerOptionVO();

            char key = (char) (65 + i);
            answerOptionVO.setKey(String.valueOf(key));
            answerOptionVO.setValue(answerOptions[i]);

            answerOptionVOS.add(answerOptionVO);
        }
        detailVO.setAnswer_option(answerOptionVOS);
        voteVO.setDetail(detailVO);

        StatisticsVO statisticsVO = new StatisticsVO();
        statisticsVO.setCount(talkRecordsVote.getAnsweredNum());
        Map<String, Long> answer_options = new HashMap<>();
        for (int i = 0; i < answerOptions.length; i++) {
            char key = (char) (65 + i);
            QueryWrapper<TalkRecordsVoteAnswer> talkRecordsVoteAnswerQueryWrapper = new QueryWrapper<>();
            talkRecordsVoteAnswerQueryWrapper.eq("vote_id", talkRecordsVote.getId()).eq("answer_option", String.valueOf(key));
            Long count = talkRecordsVoteAnswerMapper.selectCount(talkRecordsVoteAnswerQueryWrapper);
            answer_options.put(String.valueOf(key), count);
        }
        statisticsVO.setOptions(answer_options);
        voteVO.setStatistics(statisticsVO);

        List<Integer> voteUsers = new ArrayList<>();
        QueryWrapper<TalkRecordsVoteAnswer> talkRecordsVoteAnswerQueryWrapper = new QueryWrapper<>();
        talkRecordsVoteAnswerQueryWrapper.eq("vote_id", talkRecordsVote.getId());
        List<TalkRecordsVoteAnswer> talkRecordsVoteAnswers = talkRecordsVoteAnswerMapper.selectList(talkRecordsVoteAnswerQueryWrapper);
        voteUsers = talkRecordsVoteAnswers.stream().map(TalkRecordsVoteAnswer::getUserId).collect(Collectors.toList());
        voteVO.setVote_users(voteUsers);

        eventTalkDataVO.setVote(voteVO);

        eventTalkVO.setData(eventTalkDataVO);
        keepAlive.setContent(eventTalkVO);

        GetUserUtil.sendMessage(keepAlive, uid);
        groupMember.remove(uid);
        for (Integer user_id : groupMember) {
            if (GetUserUtil.isOnLine(user_id) == 1) {
                GetUserUtil.sendMessage(keepAlive, user_id);
            }
        }

        return Result.success();
    }

    /**
     * 用户投票
     * @param uid
     * @param options
     * @param record_id
     * @return
     */
    @Override
    public Result voteHandle(Integer uid, String options, Integer record_id) {
        QueryWrapper<TalkRecordsVote> talkRecordsVoteQueryWrapper = new QueryWrapper<>();
        talkRecordsVoteQueryWrapper.eq("record_id",record_id);
        TalkRecordsVote talkRecordsVote = talkRecordsVoteMapper.selectOne(talkRecordsVoteQueryWrapper);
        long time = Date.from(talkRecordsVote.getCreatedAt().toInstant(ZoneOffset.of("+8"))).getTime();

        if (talkRecordsVote!=null&&time+ JwtUtil.expiresIn>=System.currentTimeMillis()){
            QueryWrapper<TalkRecordsVoteAnswer> talkRecordsVoteAnswerQueryWrapper = new QueryWrapper<>();
            talkRecordsVoteAnswerQueryWrapper.eq("vote_id",talkRecordsVote.getId()).eq("user_id",uid);
            TalkRecordsVoteAnswer userVoteAnswer = talkRecordsVoteAnswerMapper.selectOne(talkRecordsVoteAnswerQueryWrapper);
            if (userVoteAnswer!=null){
                return Result.fail("您已参与过此次投票！");
            }

            TalkRecordsVoteAnswer talkRecordsVoteAnswer = new TalkRecordsVoteAnswer();
            talkRecordsVoteAnswer.setUserId(uid);
            talkRecordsVoteAnswer.setAnswerOption(options);
            talkRecordsVoteAnswer.setVoteId(talkRecordsVote.getId());

            talkRecordsVoteAnswerMapper.insert(talkRecordsVoteAnswer);

            talkRecordsVote.setAnsweredNum(talkRecordsVote.getAnsweredNum()+1);
            talkRecordsVoteMapper.updateById(talkRecordsVote);

            StatisticsVO statisticsVO = new StatisticsVO();
            String[] answerOptions = talkRecordsVote.getAnswerOption().split(",");
            statisticsVO.setCount(talkRecordsVote.getAnsweredNum());
            Map<String, Long> answer_options = new HashMap<>();
            for (int i = 0; i < answerOptions.length; i++) {
                char key = (char) (65 + i);
                QueryWrapper<TalkRecordsVoteAnswer> talkRecordsVoteAnswerQueryWrapper1 = new QueryWrapper<>();
                talkRecordsVoteAnswerQueryWrapper1.eq("vote_id", talkRecordsVote.getId()).eq("answer_option", String.valueOf(key));
                Long count = talkRecordsVoteAnswerMapper.selectCount(talkRecordsVoteAnswerQueryWrapper1);
                answer_options.put(String.valueOf(key), count);
            }
            statisticsVO.setOptions(answer_options);

            return Result.success(statisticsVO);
        }
        else {
            if (talkRecordsVote.getStatus()==0){
                talkRecordsVote.setStatus(1);
                talkRecordsVoteMapper.updateById(talkRecordsVote);
            }
            return Result.fail("该投票已结束");
        }
    }
}
